package com.venus.common.dao.impl;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.type.DateType;
import org.hibernate.type.FloatType;
import org.hibernate.type.IntegerType;
import org.hibernate.type.StringType;
import org.hibernate.type.Type;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.venus.common.dao.IBaseDAO;
import com.venus.common.utils.ConditionUtil;
import com.venus.component.page.PageInfo;

public class BaseDAOImpl extends HibernateDaoSupport implements IBaseDAO  {

	public void deleteModel(Object obj) {
		this.getHibernateTemplate().delete(obj);
	}

	public <T> T getModel(Class<T> clazz, Serializable id) {
		return this.getHibernateTemplate().get(clazz,id);
	}
	
	public <T> T loadModel(Class<T> clazz, Serializable id) {
		return this.getHibernateTemplate().load(clazz,id);
	}

	public void saveModel(Object obj) {
		this.getHibernateTemplate().save(obj);
	}

	public void updateModel(Object obj) {
		this.getHibernateTemplate().update(obj);
	}
	
	public void saveOrUpdateModel(Object obj) {
		this.getHibernateTemplate().saveOrUpdate(obj);
	}

	public List exeHql(String hql) {
		return this.getHibernateTemplate().find(hql);
	}

	 /**
	 * 分页查询,传一个hql语句,和一个参数数组
     * @param hql  hql语句  
     * @param bindValue  数组参数  
     * @param first  分页起点  
     * @param count  每页的记录总数  
     * @return 返回List集合  
     */  
    public List pageQuery(final String hql, final Object[] bindValue, final Integer first, final Integer count) {
		List list = this.getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = session.createQuery(hql);   
                if (bindValue != null && bindValue.length >= 1) {
                	Type[] types = typesFactory(bindValue);   
                    query.setParameters(bindValue, types);   
                }
                if (first != null && first.intValue() >= 0) {
                	query.setFirstResult(first);
                    if (count != null && count.intValue() >= 0){
                    	query.setMaxResults(count);
                    }
                }
                List result = query.list();   
                return result;                       
			}   
		});   
        return list;
    } 
  
    /**
     * 获取对象对应参数的类型  
     * @param bindValue  
     * @return  
     */  
    private final Type[] typesFactory(Object[] bindValue) {   
	        int count = bindValue.length;           
	        Type[] types = new Type[count];           
	        for (int i = 0; i < count; i++) {          
	        	if (bindValue[i].getClass().getName().endsWith("String")) {
	        		types[i] = new StringType();           
	        	} else if (bindValue[i].getClass().getName().endsWith("Integer")) {   
	        		types[i] = new IntegerType();           
	        	} else if (bindValue[i].getClass().getName().endsWith("Float")) {
	        		types[i] = new FloatType();
	        	} else if (bindValue[i].getClass().getName().endsWith("Date")) {
	        		types[i] = new DateType();
	        	}   
        }
       return types;
   	}  
    
    /**
     * 创建查询
     * @param queryString
     * @param values
     * @return
     */
    public Query createQuery(String queryString, Object... values) {   
		super.getSession().createQuery(queryString);   
		Query queryObject = super.getSession().createQuery(queryString);   
		if (values != null) {   
			for (int i = 0; i < values.length; i++) {   
				queryObject.setParameter(i, values[i]);   
			}   
		}   
		return queryObject;   
	}
    
    /**
     * hql查询,指定参数
     * @param hql
     * @param values
     * @return
     */
	public List find(String hql, Object... values) {
	    return createQuery(hql, values).list();
	} 
	
	/**
	 * 执行SQL删除所有实例
	 * @param entities
	 */
    public void delete(String strHql, Object... values){
    	Query q = this.getSession().createQuery(strHql);
    	if (values != null) {   
			for (int i = 0; i < values.length; i++) {   
				q.setParameter(i, values[i]);
			}   
		}
    	q.executeUpdate();
    }

	@Override
	public List exeHql(String strHQL, List<ConditionUtil> lstConditionUtils) {
		StringBuffer sb = new StringBuffer(128);
		sb.append(strHQL);
		for(ConditionUtil objConditionUtil : lstConditionUtils ){
			sb.append(objConditionUtil.parse2Hql());
		}
		return this.getHibernateTemplate().find(sb.toString());
	}

	public Long exeCountHql(String strHQL, Object... values) {
		Query q = this.getSession().createQuery(strHQL);
    	if (values != null) {   
			for (int i = 0; i < values.length; i++) {   
				q.setParameter(i, values[i]);
			}   
		}
    	return (Long)q.list().get(0);
	}
	
	@SuppressWarnings("unchecked")
	public PageInfo getPageInfo(String strCountHql, String strRecordHql, List<ConditionUtil> lstConditionUtils, int iPageRecord, int iCurPage){
		// 得到记录总数
		List<Long> lstCount = this.exeHql(strCountHql, lstConditionUtils);
		Long lCount = lstCount.size()>0 ? lstCount.get(0) : 0;
		// 拼接查询记录条件
		StringBuffer sbRecordHql = new StringBuffer(128);
		sbRecordHql.append(strRecordHql);
		for(ConditionUtil objConditionUtil : lstConditionUtils ){
			sbRecordHql.append(objConditionUtil.parse2Hql());
		}
		// 得到记录实例集合
        Query q = getSession().createQuery(sbRecordHql.toString()).setFirstResult((iCurPage - 1) * iPageRecord).setMaxResults(iPageRecord);
        List lstRecords = q.list();
        // 得到分页信息
		PageInfo objPageInfo = new PageInfo(lCount.intValue(), iCurPage, iPageRecord);
		// 分页信息中设置记录实例
		objPageInfo.setLstRecords(lstRecords);
        return objPageInfo;
    }
    
}
